import * as BABYLON from "babylonjs";

export class Camara3D {
    private _canvas: HTMLCanvasElement;
    private _engine: BABYLON.Engine;
    private _scene: BABYLON.Scene;
    private _camera: BABYLON.Camera;
    private _light: BABYLON.Light;
    constructor(canvasId: string) {
        this._canvas = document.getElementById(canvasId) as HTMLCanvasElement;
        this._engine = new BABYLON.Engine(this._canvas, true);
        this._scene = {} as BABYLON.Scene;
        this._camera = {} as BABYLON.Camera;
        this._light = {} as BABYLON.Light;
    }

    createScene(): void {
        this._scene = new BABYLON.Scene(this._engine);
        this._scene.ambientColor = new BABYLON.Color3(1, 1, 1); // 设置背景颜色

        // this._camera = new BABYLON.FreeCamera('mycamera', new BABYLON.Vector3(0, 5, -10), this._scene);
        // this._camera.setTarget(BABYLON.Vector3.Zero());
        // this._camera.attachControl(this._canvas, true); // 如果设置为true，canvas将会触发默认事件。

        // 1. Universal相机 扩展和取代了FreeCamera 支持键盘/鼠标/触摸屏幕/游戏手柄
        // this._camera = new BABYLON.UniversalCamera('universalCamera', new BABYLON.Vector3(0, 0, -10), this._scene);
        // this._camera.setTarget(BABYLON.Vector3.Zero()); // 使用setTarget方法设置相机交点，并传入一个场景的位置点
        // this._camera.attachControl(this._canvas, true);

        // 2. ArcRotate相机 弧形旋转相机: 相当与卫星，支持按经度和纬度围绕物体进行移动
        // this._camera = new BABYLON.ArcRotateCamera('arccamera', 0, 0, 10, new BABYLON.Vector3(0, 0, 0), this._scene);
        // this._camera.position = new BABYLON.Vector3(0, 0, 20);
        // this._camera.attachControl(this._canvas, true);

        // 3. Follow相机 跟拍相机
        // let follow: BABYLON.FollowCamera = new BABYLON.FollowCamera('followCamera', new BABYLON.Vector3(0, 0, -10), this._scene);
        // follow.radius = 30; // 在全局坐标系下相机距离场景的距离 
        // follow.heightOffset = 10; // 在局部坐标下相机的高度高于目标的高度的值
        // follow.rotationOffset = 0; // 相机在x y平面内围绕目标的局部原点旋转值
        // follow.cameraAcceleration = 0.005; // 摄像机从当前位置移动到目标位置的加速度
        // follow.maxCameraSpeed = 10; // 最大加速值
        // follow.attachControl(this._canvas, true);

        // //Different face for each side of box to show camera rotation
        // var hSpriteNb = 6;  // 6 sprites per row
        // var vSpriteNb = 4;  // 4 sprite rows	
        // var faceUV = new Array(6);
        // for (var i = 0; i < 6; i++) {
        //     faceUV[i] = new BABYLON.Vector4(i / hSpriteNb, 0, (i + 1) / hSpriteNb, 1 / vSpriteNb);
        // }
        // var box = BABYLON.MeshBuilder.CreateBox("box", { size: 2, faceUV: faceUV }, this._scene);
        // box.position = new BABYLON.Vector3(20, 0, 10);
        // follow.lockedTarget = box;

        // 4. DeviceOrient相机 - 设备相机，例如重力感应等
        let docamera: BABYLON.DeviceOrientationCamera = new BABYLON.DeviceOrientationCamera('docamera', new BABYLON.Vector3(0, 0, 0), this._scene);
        docamera.setTarget(new BABYLON.Vector3(0, 0, 10));
        docamera.angularSensibility = 10;
        docamera.attachControl(this._canvas, true);

        let sphere = BABYLON.MeshBuilder.CreateBox('mysphere', { size: 5 }, this._scene);
        sphere.position = new BABYLON.Vector3(0, 0, 10);
        let sphere2 = BABYLON.MeshBuilder.CreateBox('mysphere', { size: 3 }, this._scene);
        sphere2.position = new BABYLON.Vector3(0, 0, -10);
        let sphere3= BABYLON.MeshBuilder.CreateBox('mysphere', { size: 2 }, this._scene);
        sphere3.position = new BABYLON.Vector3(0, 10, 0);

        // 5. VR...

        // 6. Fly相机 飞行相机
        // let camera: BABYLON.FlyCamera = new BABYLON.FlyCamera('flycamera', new BABYLON.Vector3(0, -5, 10), this._scene);
        // camera.rollCorrect = 10;
        // camera.bankedTurn = true;
        // camera.bankedTurnLimit = Math.PI / 2;
        // camera.bankedTurnMultiplier = 1;
        // camera.attachControl(this._canvas, true);

        this._light = new BABYLON.HemisphericLight('mylight', new BABYLON.Vector3(0, 10, 0), this._scene);
    }

    createShape(): void {
        let sphere = BABYLON.MeshBuilder.CreateSphere('mysphere', {}, this._scene);
        sphere.scaling = new BABYLON.Vector3(3, 3, 3);
    }

    doRender(): void {
        // Run the render loop.
        this._engine.runRenderLoop(() => {
            this._scene.render();
        });

        // The canvas/window resize event handler.
        window.addEventListener('resize', () => {
            this._engine.resize();
        });
    }
}